package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.bizsys.domain.*;
import com.ruoyi.bizsys.dto.UserInfo;
import com.ruoyi.bizsys.enums.AwardEventEnum;
import com.ruoyi.bizsys.mapper.CollectionReduceOrderMapper;
import com.ruoyi.bizsys.service.IAppUserService;
import com.ruoyi.bizsys.mapper.RepaymentOrderMapper;
import com.ruoyi.bizsys.service.ICollectionReduceOrderService;
import com.ruoyi.bizsys.service.ILoanIouService;
import com.ruoyi.bizsys.service.IReduceFeeService;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.business.common.AsyncService;
import com.ruoyi.business.domain.WalletAccountVo;
import com.ruoyi.business.domain.WalletOrderReq;
import com.ruoyi.business.domain.WalletRepayReq;
import com.ruoyi.business.service.*;
import com.ruoyi.common.constant.WalletConstants;
import com.ruoyi.common.utils.uuid.IdUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * @author wqg
 * @description 处理冲账后公共业务，调用钱包的服务
 * @date 2022/6/15
 */
@Slf4j
@Service
public class DoRepaymentLastServiceImpl implements IDoRepaymentLastService {

    @Autowired
    ILoanIouService loanIouService;
    @Autowired
    private RestTemplateService restTemplateService;
    @Autowired
    private AsyncService asyncService;

    @Autowired
    IWalletService walletService;

    @Autowired
    IRepaymentSmsService iRepaymentSmsService;

    @Autowired
    RepaymentOrderMapper repaymentOrderMapper;
    @Autowired
    IAwardDistributionService awardDistributionService;
    @Autowired
    IAppUserService appUserService;
    @Autowired
    CollectionReduceOrderMapper collectionReduceOrderMapper;
    @Autowired
    IReduceFeeService iReduceFeeService;
    @Autowired
    CollectionReduceOrderService collectionReduceOrderService;

    @Override
    public void lastInitRuleInAndAutoMat(RepaymentOrder repaymentOrder) {
        LoanIou loanIou = loanIouService.getLoanIouByLoanSerialNo(repaymentOrder.getLoanSerialNo());
        //结清后自动化提额
        if (LoanIou.LOAN_IOU_STATUS_SETTLE == loanIou.getIouStatus()) {
            //发送短信-通知告诉用户还款成功
            iRepaymentSmsService.activeRepayment(repaymentOrder, loanIou, "success");
            try {
//                RuleIn ruleIn = raiseLimitParamsLoader.initRuleInParam(loanIou.getLoanSerialNo(), creditAccount.getCustNo());
                RuleIn ruleIn = restTemplateService.initRuleInParam(loanIou.getLoanSerialNo(), repaymentOrder.getCustNo());
                asyncService.automaticRaiseLimit(loanIou.getLoanSerialNo(), loanIou.getCustNo(), ruleIn);

                //分销活动
                UserInfo userInfo = appUserService.getUserInfoByCustNo(loanIou.getCustNo());
                awardDistributionService.distributionAwardTrigger(AwardEventEnum.WITHDRAW_SETTLE, userInfo.getUserId(), loanIou.getLoanPrincipal());

            } catch (Exception e) {
                log.error("客户号{}借据{}自动化提额异常", loanIou.getCustNo(), loanIou.getLoanSerialNo(), e);
            }
        }else{
            //检查是否有催收减免订单可用的,有的话进行冲账
            dealCollectionReduceOrder(loanIou,repaymentOrder.getLoanSerialNo());
        }
    }

    private void dealCollectionReduceOrder(LoanIou loanIou, String loanSerialNo) {
        CollectionReduceOrder collectionReduceOrder = collectionReduceOrderMapper.getCanUseDetailByloanSerialNo(loanSerialNo);
        if (null == collectionReduceOrder) {
            log.info("loanSerialNo:{},无可用减免订单",loanSerialNo);
            return;
        }
        BigDecimal reduceAmt = collectionReduceOrder.getReduceAmt();
        log.info("loanSerialNo:{},有可用减免订单，reduceAmt:{}",loanSerialNo,reduceAmt);
        BigDecimal needAmt = LoanIou.calculationOverdueAmount(loanIou);
        log.info("loanSerialNo:{},减免金额，reduceAmt:{},needAmt:{}",loanSerialNo,reduceAmt,needAmt);
        if(needAmt.compareTo(reduceAmt)<=0){
            ReduceFee reduceFee = new ReduceFee();
            reduceFee.setReduceSerialNo(IdUtils.reqId());
            reduceFee.setLoanSerialNo(loanIou.getLoanSerialNo());
            reduceFee.setCustNo(loanIou.getCustNo());
            reduceFee.setTotalAmt(reduceAmt);
            reduceFee.setLoanPrincipal(reduceAmt);
            reduceFee.setReduceSource("CollectionReduce");
            reduceFee.setReduceDesc("CollectionReduceOrder:催收减免订单");
            iReduceFeeService.insertReduceFee(reduceFee);

            collectionReduceOrder.setRemissionNo(reduceFee.getReduceSerialNo());
            collectionReduceOrder.setStatus(CollectionReduceOrder.ORDER_STATUS_HASUSED);
            collectionReduceOrderMapper.updateById(collectionReduceOrder);

            //冲账
            collectionReduceOrderService.repaymentCalOffset(loanIou
                    , reduceFee.getReduceSerialNo()
                    , BizConstants.LOAN_REPAYMENT_ORDER_TYPE_COLLECION_REDUCE, reduceAmt);

        }
    }

    /**
     * 调用远程的接口获取钱包并冻结钱包的钱
     *
     * @param minPay
     * @param custNo
     * @param loanSerialNo
     * @param isDeffer
     * @return
     */
    @Override
    public JSONObject getAmtWallet(BigDecimal minPay, String custNo, String loanSerialNo, boolean isDeffer) {

        WalletRepayReq walletRepayReq = new WalletRepayReq();
        walletRepayReq.setCustNo(custNo);
        walletRepayReq.setLoanSerialNo(loanSerialNo);
        walletRepayReq.setOrderType(WalletConstants.ORDER_TYPE_REPAY);
        if (isDeffer) {
            walletRepayReq.setOrderType(WalletConstants.ORDER_TYPE_DEFERRED_REPAY);
        }
        walletRepayReq.setApplyAmount(minPay);
        JSONObject json = walletService.walletRepayment(walletRepayReq);
        log.info("调用远程的接口获取钱包并冻结钱包:{}", json.toJSONString());

        JSONObject res = new JSONObject();
        res.put("amtWallet", json.getBigDecimal("actualAmt"));
        res.put("walletOrderNo", json.getString("orderSerialNo"));// 流水号可能为空，需要处理
        return res;
    }

    /**
     * 获取钱包可用金额
     *
     * @return
     */
    @Override
    public BigDecimal getWalletAmount(String custNo) {
        JSONObject jsonObject;
        try {
            jsonObject = walletService.getWalletAccount(custNo);
        } catch (Exception e) {
            log.error("获取钱包可用金额异常", e);
            return BigDecimal.ZERO;
        }
        WalletAccountVo walletAccountVo = JSONObject.parseObject(jsonObject.toJSONString(), WalletAccountVo.class);
        if (WalletConstants.WALLET_STATUS_NORMAL.equals(walletAccountVo.getWalletStatus())) {
            return walletAccountVo.getWalletAmount();
        }
        if (WalletConstants.WALLET_STATUS_BALANCE_LOCK.equals(walletAccountVo.getWalletStatus())) {
            return walletAccountVo.getBonus();
        }
        if (WalletConstants.WALLET_STATUS_BONLUS_LOCK.equals(walletAccountVo.getWalletStatus())) {
            return walletAccountVo.getBalance();
        }
        log.warn("钱包状态不可用或异常,walletStatus{}", walletAccountVo.getWalletStatus());
        return BigDecimal.ZERO;
    }

    /**
     * 解冻钱包-冲账成功
     *
     * @param repaymentOrder
     */
    @Override
    public void updateWalletOrderToSuccess(RepaymentOrder repaymentOrder, boolean isDeffer) {
        WalletOrderReq walletOrderReq = WalletOrderReq.builder()
                .orderSerialNo(repaymentOrder.getPayTransSerialNo())
                .approvalStatus(WalletConstants.WALLET_ORDER_STATUS_SUCCESS)
                .orderType(isDeffer ? WalletConstants.ORDER_TYPE_DEFERRED_REPAY : WalletConstants.ORDER_TYPE_REPAY).build();
        walletService.updateWalletOrder(walletOrderReq);
    }

    /**
     * 解冻钱包--冲账失败
     *
     * @param orderSerialNo
     */
    @Override
    public void updateWalletOrderToFailed(String orderSerialNo, boolean isDeffer) {
        WalletOrderReq walletOrderReq = WalletOrderReq.builder()
                .orderSerialNo(orderSerialNo)
                .approvalStatus(WalletConstants.WALLET_ORDER_STATUS_FAILED)
                .orderType(isDeffer ? WalletConstants.ORDER_TYPE_DEFERRED_REPAY : WalletConstants.ORDER_TYPE_REPAY).build();
        walletService.updateWalletOrder(walletOrderReq);
    }


}
